<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
  xmlns:math="http://exslt.org/math" 
  xmlns:exsl="http://exslt.org/common" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  extension-element-prefixes="exsl math" 
  exclude-result-prefixes="math">

  <xsl:param name="html_href"/>

  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" 
    cdata-section-elements="script"
    doctype-public="-//W3C//DTD SVG 1.0/EN"
    doctype-system="http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"/>
  
  <!-- These parameters control the proportions of the tree -->
  <!-- and its nodes -->  
  <xsl:template match="/grid">
    <svg 
      xmlns:a3="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
      xmlns:xlink="http://www.w3.org/1999/xlink"
      a3:scriptImplementation="Adobe" onload="init(evt)">
      
      <script type="text/ecmascript" a3:scriptImplementation="Adobe"
        xlink:href="{$html_href}/static/js/ep_svg.js" />

      <xsl:apply-templates/>
    </svg>
  </xsl:template>

  <xsl:template match="cell">
    <xsl:variable name="cellWidth" select="@width"/>
    <xsl:variable name="cellHeight" select="@height"/>
    <xsl:variable name="cellX" select="@x"/>
    <xsl:variable name="cellY" select="@y"/>

    <xsl:apply-templates>
      <xsl:with-param name="cellWidth" select="$cellWidth"/>
      <xsl:with-param name="cellHeight" select="$cellHeight"/>
      <xsl:with-param name="cellX" select="$cellX"/>
      <xsl:with-param name="cellY" select="$cellY"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="tree">
    <xsl:param name="cellWidth"/>
    <xsl:param name="cellHeight"/>
    <xsl:param name="cellX"/>
    <xsl:param name="cellY"/>

    <xsl:variable name="rotate" select="@rotate"/>
    
    <xsl:if test="$rotate=0">
      <xsl:variable name="width" select="$cellWidth"/>
      <xsl:variable name="height" select="$cellHeight"/>
      
      <g transform="translate({$cellX}, {$cellY})">
        <xsl:variable name="nodeWidth" select="$width div @leaves"/>      
        <xsl:variable name="horzSpace" select="$nodeWidth div 2"/>
        <!-- Capture the subtree of this node in a variable -->
        <xsl:variable name="subTree">
          <xsl:apply-templates>
            <xsl:with-param name="cellWidth" select="$width"/>
            <xsl:with-param name="cellHeight" select="($height)-8"/>                  
            <xsl:with-param name="nodeWidth" select="$nodeWidth"/>
            <xsl:with-param name="horzSpace" select="$horzSpace"/>
          </xsl:apply-templates>
        </xsl:variable>
        <xsl:copy-of select="exsl:node-set($subTree)/g/*"/>
      </g>
    </xsl:if>

    <xsl:if test="$rotate=90">
      <xsl:variable name="width" select="$cellHeight"/>
      <xsl:variable name="height" select="$cellWidth"/>
      <xsl:variable name="yTrans" select="-($cellX+$height)"/>
      <xsl:variable name="xTrans" select="$cellY"/>

      <!--    <g transform=" rotate({@rotate}, {($cellHeight div 2)}, {($cellHeight div 2)}) translate({$xTrans},{$yTrans})">  -->
      <g transform=" rotate({@rotate}) translate({$xTrans},{$yTrans})">
        <xsl:variable name="nodeWidth" select="$width div @leaves"/>      
        <xsl:variable name="horzSpace" select="$nodeWidth div 2"/>
        <!-- Capture the subtree of this node in a variable -->
        <xsl:variable name="subTree">
          <xsl:apply-templates>
            <xsl:with-param name="cellWidth" select="$width"/>
            <xsl:with-param name="cellHeight" select="($height)-8"/>                  
            <xsl:with-param name="nodeWidth" select="$nodeWidth"/>
            <xsl:with-param name="horzSpace" select="$horzSpace"/>
          </xsl:apply-templates>
        </xsl:variable>
        <xsl:copy-of select="exsl:node-set($subTree)/g/*"/>
      </g>        
    </xsl:if>

    <xsl:if test="$rotate=-90">
      <xsl:variable name="width" select="$cellHeight"/>
      <xsl:variable name="height" select="$cellWidth"/>
      <xsl:variable name="xTrans" select="-($width+$cellY)"/>
      <xsl:variable name="yTrans" select="$cellX"/>

      <g transform=" rotate({@rotate}) translate({$xTrans},{$yTrans})">
        <xsl:variable name="nodeWidth" select="$width div @leaves"/>
        <xsl:variable name="horzSpace" select="$nodeWidth div 2"/>
        <!-- Capture the subtree of this node in a variable -->
        <xsl:variable name="subTree">
          <xsl:apply-templates>
            <xsl:with-param name="cellWidth" select="$width"/>
            <xsl:with-param name="cellHeight" select="$height"/>                
            <xsl:with-param name="nodeWidth" select="$nodeWidth"/>
            <xsl:with-param name="horzSpace" select="$horzSpace"/>
          </xsl:apply-templates>
        </xsl:variable>
        <xsl:copy-of select="exsl:node-set($subTree)/g/*"/>
      </g>        
    </xsl:if>
  </xsl:template>

  <!-- This matches all non-leaf nodes -->  
  <xsl:template match="node">
    <xsl:param name="cellWidth"/>
    <xsl:param name="cellHeight"/>
    <xsl:param name="nodeWidth"/>
    <xsl:param name="horzSpace"/>
    <xsl:variable name="subTree">
      
      <xsl:apply-templates>
        <xsl:with-param name="cellWidth" select="$cellWidth"/>
        <xsl:with-param name="cellHeight" select="$cellHeight"/>
        <xsl:with-param name="nodeWidth" select="$nodeWidth"/>
        <xsl:with-param name="horzSpace" select="$horzSpace"/>
      </xsl:apply-templates>  
    </xsl:variable>
    
    <!-- Position this node horizontally based on the average -->
    <!-- position of its children -->
    <xsl:variable name="thisX" select="sum(exsl:node-set($subTree)/*/@THISX) div 2"/>
    <xsl:variable name="X1" select="number(exsl:node-set($subTree)/*[1]/@THISX)"/>
    <xsl:variable name="X2" select="number(exsl:node-set($subTree)/*[2]/@THISX)"/>
    
    <!-- Position this node vertically based on its level -->
    <xsl:variable name="thisY" select="$cellHeight*(1-@dist)"/>
    
    <!-- We place the parent and its children and the connectors -->
    <!-- in a group -->
    <!-- We also add bookkeeping attributes to the group as a means of -->
    <!--passing information up the tree -->
    <g THISX="{$thisX}" X1="{$X1}" X2="{$X2}" THISY="{$thisY}">
    
      <!--Draw connecting line between current node and its children -->        
      <xsl:call-template name="drawSquareConnections">
        <xsl:with-param name="xParent" select="$thisX"/>
        <xsl:with-param name="yParent" select="$thisY"/>
        <xsl:with-param name="X1Parent" select="$X1"/>
        <xsl:with-param name="X2Parent" select="$X2"/> 
        <xsl:with-param name="children" select="exsl:node-set($subTree)/g"/>
      </xsl:call-template>
      
      <!--Copy the SVG of the sub tree -->
      <xsl:copy-of select="exsl:node-set($subTree)"/>
    </g>
  </xsl:template>

  <!-- This matches all leaf nodes -->  
  <xsl:template match="leaf">
    <xsl:param name="cellHeight"/>
    <xsl:param name="nodeWidth"/>
    <xsl:param name="horzSpace"/>
    <xsl:variable name="hpos" select="@order"/>
    <xsl:variable name="id" select="@id"/>
    <!-- Position leaf nodes horizontally based on the number of -->
    <!-- preceding leaf nodes -->
    <!--  <xsl:variable name="X" select="$horzSpace+($nodeWidth*count(preceding::leaf))"/> -->
    <!-- <xsl:variable name="X" select="$horzSpace+($nodeWidth*(count(preceding::leaf)))-(count(preceding::tree)*4*$nodeWidth)"/>-->
    <xsl:variable name="X" select="$horzSpace+($nodeWidth*(ancestor::tree/leafOrder/leaf[@id_ref=$id]/@order))"/>
    
    <!-- Position this node vertically based on its level -->
    <xsl:variable name="Y" select="$cellHeight"/> 
    <g THISX="{$X}" THISY="{$Y}" type="leaf"/>
  </xsl:template>

  <!-- Square connections take the shortest path using only horizontal -->
  <!-- and vertical lines from center of parent bottom to center of -->   
  <!-- child top -->
  <xsl:template name="drawSquareConnections">
    <xsl:param name="xParent"/>
    <xsl:param name="X1Parent"/>
    <xsl:param name="X2Parent"/>
    <xsl:param name="yParent"/>
    <xsl:param name="children"/>
    <!--central horizontal line -->
    <line onclick="line_click(evt)" x1="{$X1Parent}" y1="{$yParent}" x2="{$X2Parent}" y2="{$yParent}" style="stroke: black; stroke-width:0.3;"/> 

    <!--vertical child lines -->
    <line onclick="line_click(evt)"  x1="{$X1Parent}" y1="{$yParent}"  x2="{$X1Parent}" y2="{$children[1]/@THISY}" style="stroke: black; stroke-width:0.3;"/>  
    <line onclick="line_click(evt)"  x1="{$X2Parent}" y1="{$yParent}"  x2="{$X2Parent}" y2="{$children[2]/@THISY}" style="stroke: black; stroke-width:0.3;"/>  
  </xsl:template>

  <xsl:template match="heatmap">
    <xsl:param name="cellWidth"/>
    <xsl:param name="cellHeight"/>
    <xsl:param name="cellX"/>
    <xsl:param name="cellY"/>
     
    <g transform=" translate({$cellX},{$cellY})">
      <xsl:variable name="conditions" select="@conditions"/>
      <xsl:variable name="features" select="@features"/>      
      <xsl:apply-templates>
        <xsl:with-param name="heatCellHeight" select="$cellHeight div $features"/>
        <xsl:with-param name="heatCellWidth" select="$cellWidth div $conditions"/>
      </xsl:apply-templates>
    </g>
  </xsl:template>
  
  <xsl:template match="ratio">
    <xsl:param name="heatCellHeight"/>
    <xsl:param name="heatCellWidth"/>
    <xsl:variable name="vPos" select="@row"/>
    <xsl:variable name="hPos" select="@column"/>
    
    <rect x="{$hPos*$heatCellWidth}" y="{$vPos*$heatCellHeight}" width="{$heatCellWidth}" height="{$heatCellHeight}" style="fill:rgb({@r},{@g},0)"/>
  </xsl:template>
  
  <xsl:template match="lineplot">
    <xsl:param name="cellWidth"/>
    <xsl:param name="cellHeight"/>
    <xsl:param name="cellX"/>
    <xsl:param name="cellY"/>
    
    <xsl:variable name="scaleX" select="$cellWidth div 300"/>
    <xsl:variable name="scaleY" select="$cellHeight div 180"/>   
    
    <g transform="translate({$cellX},{$cellY})">
      <g transform="scale({$scaleX} {$scaleY})">
        <xsl:apply-templates>
          <xsl:with-param name="scaleX" select="$scaleX"/>
          <xsl:with-param name="scaleY" select="$scaleY"/>
          <xsl:with-param name="cellX"  select="$cellX"/>
          <xsl:with-param name="cellY"  select="$cellY"/>
        </xsl:apply-templates>
      </g>
    </g>
  </xsl:template>
  
  <xsl:template match="line">
    <line x1="{@x1}" y1="{@y1}"  x2="{@x2}" y2="{@y2}" stroke="{@stroke}" stroke-width="{@stroke-width}"/>
  </xsl:template>
  
  <xsl:template match="rect">
    <rect x="{@x}" y="{@y}" width="{@width}" height="{@height}" id="{@id}" fill="{@fill}" onclick="{@onclick}" onmouseover="{@onmouseover}"/>
  </xsl:template>
    
  <xsl:template match="polyline">
    <polyline stroke="{@stroke}" stroke-width="{@stroke-width}"  points="{@points}" fill="{@fill}" id="{@id}"/>
  </xsl:template>
  
  <xsl:template match="text">
    <text x="{@x}" y="{@y}" font-family="{@font-family}" font-size="{@font-size}" fill="{@fill}">
      <xsl:value-of select="@message"/>
    </text>
  </xsl:template>
  
  <xsl:template match="vhook">
    <xsl:copy-of select="."/>
  </xsl:template>
  
  <xsl:template match="hhook">
    <xsl:copy-of select="."/>
  </xsl:template>

  <xsl:template match="annotation">
    <xsl:param name="cellWidth"/>
    <xsl:param name="cellHeight"/>
    <xsl:param name="cellX"/>
    <xsl:param name="cellY"/>
    <xsl:if test="@rotate=0">
      <g transform="translate({$cellX},{$cellY})">
        <xsl:apply-templates>
          <xsl:with-param name="textCellHeight" select="$cellHeight div @features"/>
          <xsl:with-param name="cellWidth" select="$cellWidth"/>
        </xsl:apply-templates>
      </g>
    </xsl:if>
    <xsl:if test="@rotate!=0">
      <xsl:variable name="xTrans" select="-($cellHeight+$cellY)"/>
      <xsl:variable name="yTrans" select="$cellX"/>
        
      <g transform="rotate({@rotate}) translate({$xTrans},{$yTrans})">
        <xsl:apply-templates>
          <xsl:with-param name="textCellHeight" select="$cellWidth div @features"/>
          <xsl:with-param name="cellWidth" select="$cellHeight"/>
        </xsl:apply-templates>
      </g>
    </xsl:if>
  </xsl:template>
    
  <xsl:template match="eptext">
    <xsl:param name="textCellHeight"/>
    <xsl:param name="cellWidth"/>
    <text x="20" y="{($textCellHeight div 2)+(@row*$textCellHeight)}" font-family="{@font-family}" font-size="{@font-size}" fill="{@fill}">
      <xsl:value-of select="@message"/>
    </text> 
  </xsl:template>

</xsl:stylesheet>
